package ar.uade.distribuidas.tpo.dao;

import java.util.LinkedList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.joda.time.LocalDate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import ar.uade.distribuidas.tpo.base.utils.FormatUtils;
import ar.uade.distribuidas.tpo.dba.dominio.Cliente;
import ar.uade.distribuidas.tpo.dba.dominio.Cotizacion;
import ar.uade.distribuidas.tpo.dba.dominio.Empresa;
import ar.uade.distribuidas.tpo.dba.dominio.ItemSolicitudDeCotizacion;
import ar.uade.distribuidas.tpo.dba.dominio.OrdenDePedido;
import ar.uade.distribuidas.tpo.dba.dominio.Rodamiento;

public class OrdenDePedidoXmlDao {

	private static OrdenDePedidoXmlDao instance;

	private Document doc;
	private static final String FILE_NAME = "orden-de-pedido.xml";

	public static OrdenDePedidoXmlDao getInstancia() {
		if (instance == null) {
			instance = new OrdenDePedidoXmlDao();
			instance.createDocument();
		}
		return instance;
	}

	private OrdenDePedidoXmlDao() {
	}

	private void createDocument() {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder;
		try {
			builder = factory.newDocumentBuilder();
			doc = builder.parse(FILE_NAME);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// FIXME return list
	public OrdenDePedido getOrdenDePedido() {
		List<OrdenDePedido> odps = new LinkedList<>();
		NodeList nodos = doc.getElementsByTagName("OrdenDePedido");

		for (int i = 0; i < nodos.getLength(); i++) {
			odps.add(mapOrdenDePedido((Element) nodos.item(i)));
		}

		return odps.get(0);
	}

	private OrdenDePedido mapOrdenDePedido(Element ordenDePedidoXml) {
		OrdenDePedido odp = new OrdenDePedido();

		// TODO no nos lo da el cliente
		int numero = Integer.parseInt(ordenDePedidoXml.getAttribute("numero"));
		Element fechaXml = (Element) ordenDePedidoXml.getElementsByTagName("Fecha").item(0);
		LocalDate fecha = LocalDate.parse(fechaXml.getTextContent(), FormatUtils.DATE_FORMATTER);

		odp.setNumero(numero);
		odp.setFecha(fecha);

		Element clienteXml = (Element) ordenDePedidoXml.getElementsByTagName("Cliente").item(0);
		Long cuil = Long.parseLong(clienteXml.getElementsByTagName("Cuil").item(0).getTextContent());
		// FIXME usar IGestionCliente
		// gestionCliente.getCliente(cuil);
		Cliente cliente = new Empresa();
		cliente.setCuil(cuil);

		odp.setCliente(cliente);

		Element referenciaXml = (Element) ordenDePedidoXml.getElementsByTagName("Referencia").item(0);
		NodeList cotizacionesXml = referenciaXml.getElementsByTagName("Cotizacion");

		for (int i = 0; i < cotizacionesXml.getLength(); i++) {
			Element cotizacionXml = (Element) cotizacionesXml.item(i);
			Cotizacion cotizacion = this.mapCotizacion(cotizacionXml);

			Element rodamientoXml = (Element) cotizacionXml.getElementsByTagName("Rodamientos").item(0);
			NodeList itemsXml = rodamientoXml.getElementsByTagName("Item");

			List<ItemSolicitudDeCotizacion> items = new LinkedList<>();
			odp.getItemsPorCotizacion().put(cotizacion, items);

			for (int j = 0; j < itemsXml.getLength(); j++) {
				ItemSolicitudDeCotizacion itemCotizacion = this.mapItemCotizacion((Element) itemsXml.item(j));
				System.out.println(itemCotizacion);
				items.add(itemCotizacion);
			}
		}

		return odp;
	}

	private Cotizacion mapCotizacion(Element cotizacionXml) {
		int idCotizacion = Integer.parseInt(cotizacionXml.getElementsByTagName("Numero").item(0).getTextContent());
		// FIXME usar IGestionCotizacion
		Cotizacion c = new Cotizacion();
		c.setId(idCotizacion);
		return c;
	}

	private ItemSolicitudDeCotizacion mapItemCotizacion(Element itemXml) {
		Long nroSerie = Long.parseLong(itemXml.getAttribute("serie"));
		// FIXME usar IGestionRodamiento
		// gestionRodamiento.getRodamiento(nroSerie);
		Rodamiento rodamiento = new Rodamiento();
		rodamiento.setNroSerie(nroSerie);

		Integer cantidad = Integer.parseInt(itemXml.getElementsByTagName("Cantidad").item(0).getTextContent());

		ItemSolicitudDeCotizacion itemCotizacion = new ItemSolicitudDeCotizacion();
		itemCotizacion.setRodamiento(rodamiento);
		itemCotizacion.setCantidad(cantidad);

		return itemCotizacion;
	}

	public static void main(String[] args) {
		OrdenDePedido odp = OrdenDePedidoXmlDao.getInstancia().getOrdenDePedido();
		System.out.println(odp);
	}

}
